package xin.nick.util;

import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import xin.nick.util.domain.AccessTokenRequest;
import xin.nick.util.domain.AccessTokenResponse;
import xin.nick.util.domain.MeResponse;

/**
 * Coding Open 开发平台工具
 * @author Nick
 * @since 2023/4/4
 */
@Slf4j
public class CodingOpenUtil {

    /**
     * 基础url
     */
    private static final String BASE_URL_TEMPLATE = "https://%s.coding.net";
    /**
     * 授权链接
     */
    private static final String AUTHORIZE_URL = "/oauth_authorize.html";

    /**
     * 获取AccessToken链接
     */
    private static final String OAUTH_ACCESS_TOKEN_URL = "/api/oauth/access_token";

    /**
     * 获取当前用户信息
     */
    private static final String GET_ME_URL = "/api/me";


    /**
     * 获取当前用户信息
     * @param yourTeam
     * @param accessToken
     * @return
     */
    public static MeResponse getMe(String yourTeam, String accessToken) {
        String url = new StringBuilder(String.format(BASE_URL_TEMPLATE, yourTeam))
                .append(GET_ME_URL)
                .append("?access_token")
                .append(accessToken)
                .toString();
        log.info("get Me request: url: {}", url);
        String responseBody = HttpUtil.createRequest(Method.GET, url).execute().body();
        log.info("get Me request: response: {}", responseBody);
        MeResponse meResponse = JSON.parseObject(responseBody, MeResponse.class);
        return meResponse;

    }

    /**
     * 获取访问用的AccessToken
     * @param yourTeam
     * @param clientId
     * @param clientSecret
     * @param code
     * @return
     */
    public static AccessTokenResponse getAccessToken(String yourTeam, String clientId, String clientSecret, String code) {

        /*
            your-team：团队域名前缀；
            client_id：应用详情页的 Client ID；
            client_secret：应用详情页的 Client Secret；
            code：上一步获取的授权码；
            grant_type：授权类型，固定为 authorization_code；
         */

        String postUrl = new StringBuilder(String.format(BASE_URL_TEMPLATE, yourTeam))
                .append(OAUTH_ACCESS_TOKEN_URL)
                .toString();


        AccessTokenRequest accessTokenRequest = new AccessTokenRequest();
        accessTokenRequest.setCode(code)
                .setGrantType("authorization_code")
                .setClientId(clientId)
                .setClientSecret(clientSecret);

        String bodyString = JSON.toJSONString(accessTokenRequest);
        log.info("Access token request: url: {}, body: {}", postUrl, bodyString);
        String responseBody = HttpUtil.createRequest(Method.POST, postUrl).body(bodyString).execute().body();
        log.info("Access token request: response: {}", responseBody);
        AccessTokenResponse accessTokenResponse = JSON.parseObject(responseBody, AccessTokenResponse.class);
        return accessTokenResponse;

    }


    /**
     * 获取授权链接
     * @param yourTeam
     * @param clientId
     * @param redirectUrl
     * @param scope
     * @return
     */
    public static String getAuthorizeUrl(String yourTeam, String clientId, String redirectUrl, String scope) {

        // 参数说明：
        //
        //your-team：团队域名前缀；
        //client_id：应用详情页的 Client ID；
        //redirect_uri：应用详情页填写的回调地址；
        //response_type：返回类型，固定为 code；
        //scope：授权范围，以逗号分隔，包括：

        /**
         *
         scope 名称	授权	说明
         user	读	获取用户信息（名称、头像等 ）
         user:email	读	读取用户的 email
         notification	读/写	读取用户通知信息
         project	读	授权项目信息、项目列表，仓库信息，公钥列表、成员
         project:api_doc	发布	授权发布 API 文档
         project:artifacts	读/写	授权推送、拉取制品库
         project:depot	读/写	完整的仓库控制权限
         project:file	读/写	授权读取与操作文件
         project:issue	读/写	授权读取与操作项目协同模块
         project:key	读/写	授权读取与操作部署公钥和个人公钥
         project:members	读/写	授权项目管理者读取与操作成员
         project:notice	读/写	授权发布、删除、查询项目公告接口
         */

        // ?client_id=&redirect_uri
        String authorizeUrl = new StringBuilder(String.format(BASE_URL_TEMPLATE, yourTeam))
                .append(AUTHORIZE_URL)
                .append("?response_type=code")
                .append("&client_id=")
                .append(clientId)
                .append("&redirect_uri=")
                .append(redirectUrl)
                .append("&scope=")
                .append(scope)
                .toString();

        log.info("building authorization url: {} " + authorizeUrl);

        return authorizeUrl;
    }

}
